package com.zwd.cases.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.util.Arrays;

/**
 * @Description 面向切面编程（AOP）能够在不修改原有代码的情况下，通过切面（Aspect）来实现对代码的增强或者横切关注点的分离。
 * 常见的应用场景包括日志记录、性能统计、安全控制、事务处理等。下面是一个简单的例子，使用AOP实现对方法执行时间的统计：
 * @Author zhengwd
 * @Date 2023/4/11 22:03
 **/
//@Component
//@Aspect
public class TimeAspect {

    /**
     * 定义一个切点，匹配com.zwd.cases包及其子包下的所有类的所有方法
     */
    @Pointcut("execution(* com.zwd.cases..*.*(..))")
    public void pointcut() {}

    /**
     * 定义一个前置通知，在目标方法执行前输出开始时间
     * @param joinPoint
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("开始执行：" + joinPoint.getSignature() + "，参数：" + Arrays.toString(joinPoint.getArgs()));
        joinPoint.getArgs();
    }

    /**
     * 定义一个后置通知，在目标方法执行后输出结束时间和执行时间
     * @param joinPoint
     * @param result
     */
    @AfterReturning(pointcut = "pointcut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("执行完成：" + joinPoint.getSignature() + "，返回值：" + result);
    }

    /**
     * 定义一个异常通知，在目标方法抛出异常时输出异常信息
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "pointcut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        System.out.println("执行出错：" + joinPoint.getSignature() + "，异常信息：" + e.getMessage());
    }

}
